The approaches described in this section are approaches that could be pursued, but not necessarily approaches that have been previously conceived or pursued. Therefore, unless otherwise indicated, it should not be assumed that any of the approaches described in this section qualify as prior art merely by virtue of their inclusion in this section.
Many computer programming environments involve computer code that is intended to be executed in a managed execution mode. That is, a coordinating process or processes manages execution of the computer code by providing various services to the computer code for performing common administrative tasks. The coordinating process(es) are collectively referred to herein as a “runtime system,” or simply “runtime.” The exact services provided in a managed execution mode vary depending on the embodiment, but may include without limitation any or all of garbage collection, other memory management operations, thread management, lock management, task scheduling, profiling, optimizations, dynamic compilation, and so forth.
For various reasons, however, it is sometimes desirable to execute instructions outside of a managed execution mode. For example, there may be certain types of operations that cannot be satisfactorily performed within the managed execution mode. This may be for a variety of reasons. For instance, the operations may make “unsafe” use of a memory area, which would not be allowed by constraints enforced in the managed execution mode. Or, the operations may involve communicating with a driver or other component that does not provide an interface that may be used in the managed execution mode. Or, the non-managed instructions may be capable of performing the operations significantly faster than would be possible in the managed execution mode, on account of not requiring the overhead of providing the runtime services.
Accordingly, some programming environments allow a computer program to temporarily exit the managed execution mode and execute “native” code segments in a “native execution mode” outside of the managed execution mode. Execution of the native code segments in the native execution mode occurs without the managing runtime providing some or all of the aforementioned services. Instead, execution of the native code segments may be managed by an entirely different runtime that does not provide the same set of services or even necessarily any services. Or, the native code may be in a machine language that is directly executable by a processor without any management from a runtime. Upon completion of executing a native code segment, execution of the computer program resumes in the managed execution mode. For instance, in the Java programming language, it is possible to instruct a thread to transition from Java code to native code (such as compiled C code), execute the native code, and then transition back to the Java code.
However, while it is sometimes useful to transition from managed execution mode to native execution mode and back again, the overhead costs involved in making such transitions are often high enough to deter the use of such transitions when executing the native code might otherwise be useful. Or, the overhead costs may encourage undesirable programming practices such as remaining in native mode to run code that would be better suited for managed mode, simply because the programmer intends to return to native mode again, and does not want to incur additional transition costs.